package com.ruin.tech.ahri.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ruin.tech.ahri.model.dto.ChangePwdDTO;
import com.ruin.tech.ahri.model.dto.WeiXinAuthDTO;
import com.ruin.tech.ahri.result.Result;
import com.ruin.tech.ahri.model.dto.User;
import com.ruin.tech.ahri.model.vo.LoginInfoVO;
import com.ruin.tech.ahri.result.ResultCode;
import com.ruin.tech.ahri.service.INoticeService;
import com.ruin.tech.ahri.service.IUserService;
import com.ruin.tech.ahri.result.ResultFactory;
import com.ruin.tech.ahri.utils.Utils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.validation.Valid;
import java.util.Date;
import java.util.Objects;

/**
 * @program ahri
 * @description: 用户控制器
 * @author: ruin
 * @create: 2019/06/25 08:29
 */
@Slf4j
@Api(value = "用户业务",protocols = "https")
@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Value("${weixin.minprogram.app.id}")
    private String appId;

    @Value("${weixin.minprogram.app.secret}")
    private String appSecret;

    @Autowired
    public IUserService userService;

    @Autowired
    public INoticeService noticeService;

    @Autowired
    RestTemplate restTemplate;

    @ApiOperation(value = "非授权登陆", notes = "非授权登陆", tags = "User",httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user",paramType = "body",value = "用户对象", required = true, dataType = "User")
    })
    @ApiResponses({
            @ApiResponse(code=0,message="成功",response=LoginInfoVO.class),
            @ApiResponse(code=999,message="系统异常"),
            @ApiResponse(code=996,message="登陆失败"),
    })
    @PostMapping(value = "/login", produces = "application/json;charset=utf-8")
    public Result login(@Valid @RequestBody User user) {
        LoginInfoVO loginInfoVO = null;
        try{
            String loginName = user.getUserName();
            if(Objects.isNull(loginName)){
                loginName = user.getMobile();
            }
            if(Objects.isNull(loginName)){
                loginName = user.getEmail();
            }
            String password = user.getPassword();

            loginInfoVO = userService.login(loginName,password);
            if (Objects.isNull(loginInfoVO)) {
                log.error("登陆失败："+user.toString());
                return ResultFactory.buildFailResult(ResultCode.LOGIN_FAIL);
            }
        }catch (Exception e){
            log.error("登陆失败："+user.toString(),e);
            return ResultFactory.buildFailResult(ResultCode.LOGIN_FAIL);
        }

        return ResultFactory.buildSuccessResult(loginInfoVO);
    }

    @ApiOperation(value = "微信授权登陆", notes = "微信授权登陆", tags = "User",httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "weiXInAuthDTO", value = "授权入参对象", required = true, dataType = "WeiXInAuthDTO")
    })
    @ApiResponses({
            @ApiResponse(code=0,message="成功",response=String.class),
    })
    @PostMapping(value = "/auth/login", produces = "application/json;charset=utf-8")
    public Result login(@RequestBody WeiXinAuthDTO weiXinAuthDTO) {
        String code = weiXinAuthDTO.getCode();
        String sessionId = weiXinAuthDTO.getSessionId();

        User user = null;
        //第一次登陆或者checkSession监测 session_key已经过期，需要通过code进行,获取前端sessionId为空时
        if(code != null){
            String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid={1}&secret={2}&js_code={3}&grant_type=authorization_code";
            String code2SessionStr = restTemplate.getForEntity(code2SessionUrl, String.class,appId, appSecret, code).getBody();
            Gson gson = new GsonBuilder().serializeNulls().create();
            WeiXinAuthDTO weiXinAuthDTO1 = gson.fromJson(code2SessionStr,WeiXinAuthDTO.class);
            weiXinAuthDTO.setSession_key(weiXinAuthDTO1.getSession_key());
            weiXinAuthDTO.setOpenid(weiXinAuthDTO1.getOpenid());
            user = userService.insertOrUpdateByOpenid(weiXinAuthDTO);
        }else if(sessionId!=null && !"".equals(sessionId)){
            user = userService.insertOrUpdateBySessionId(weiXinAuthDTO);
        }else{
            return ResultFactory.buildFailResult(ResultCode.PARAM_ERROR);
        }
        return ResultFactory.buildSuccessResult(user);
    }

    @PostMapping(value = "/register", produces = "application/json;charset=utf-8")
    public Result register(@Valid @RequestBody User user) {
        try{
            user.setRoleId(2L);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            userService.register(user);
        }catch (DuplicateKeyException e){
            log.error("注册失败："+user.toString(),e);
            return ResultFactory.buildFailResult(ResultCode.REGISTER_FAIL_BY_DUPLICATE_KEY);
        }catch (Exception e){
            log.error("注册失败："+user.toString(),e);
            return ResultFactory.buildFailResult(ResultCode.REGISTER_FAIL);
        }
        return ResultFactory.buildSuccessResult(null);
    }

    @PostMapping(value = "/sendIdCodeByEmail", produces = "application/json;charset=utf-8")
    public Result sendIdCodeByEmail(@RequestBody ChangePwdDTO changePwdDTO) throws Exception {
        String email = changePwdDTO.getEmail();
        String userName = changePwdDTO.getUserName();
        if(userName == null || userName.trim().length() == 0){
            log.error("用户名为空,验证码发送失败email："+changePwdDTO.toString());
            return ResultFactory.buildFailResult(ResultCode.SEND_IDCODE_EMPTY_USER_FAIL);
        }

        if(email == null || email.trim().length() == 0){
            log.error("邮箱为空,验证码发送失败email："+changePwdDTO.toString());
            return ResultFactory.buildFailResult(ResultCode.SEND_IDCODE_EMPTY_EMAIL_FAIL);
        }

        noticeService.sendIdCode(changePwdDTO);
        return ResultFactory.buildSuccessResult(null);
    }

    @PostMapping(value = "/changePwd", produces = "application/json;charset=utf-8")
    public Result changePwd(@RequestBody ChangePwdDTO changePwdDTO) throws Exception {
        String userName = changePwdDTO.getUserName();
        if(userName == null || userName.trim().length() == 0){
            log.error("用户名不能为空");
            return ResultFactory.buildFailResult(ResultCode.USERNAME_NOT_ALLOW_EMPTY);
        }
        User user = new User();
        user.setUserName(userName);
        //查询该用户名的账号信息
        user = userService.findUserByUniqueKey(user);
        if(user == null){
            log.error("用户不存在");
            return ResultFactory.buildFailResult(ResultCode.USER_NOT_EXIST);
        }

        String mobile = changePwdDTO.getMobile();
        if(mobile == null || mobile.trim().length() < 11){
            log.error("手机号不正确");
            return ResultFactory.buildFailResult(ResultCode.MOBILE_INCORRECT);
        }else if(!user.getMobile().equals(mobile)){
            log.error("注册手机号不正确");
            return ResultFactory.buildFailResult(ResultCode.MOBILE_INCORRECT);
        }

        String newPassword = changePwdDTO.getNewPassword();
        if(newPassword == null || newPassword.trim().length() < 6){
            log.error("新密码不正确");
            return ResultFactory.buildFailResult(ResultCode.NEW_PASSWORD_INCORRECT);
        }

        Integer repairIndex = changePwdDTO.getRepairIndex();
        if(repairIndex == 0){
            String email = changePwdDTO.getEmail();
            if(email == null || email.trim().length() == 0){
                log.error("邮箱不能为空");
                return ResultFactory.buildFailResult(ResultCode.EMAIL_NOT_ALLOW_EMPTY);
            }else if(!email.equals(user.getEmail())){
                log.error("邮箱不正确");
                return ResultFactory.buildFailResult(ResultCode.EMAIL_INCORRECT);
            }

            Integer idCodeCache = noticeService.getCache(email);

            Integer idCode = changePwdDTO.getIdCode();
            if(idCode == null){
                log.error("验证码不正确"+changePwdDTO.toString());
                return ResultFactory.buildFailResult(ResultCode.IDCODE_INCORRECT);
            }else if(idCodeCache == null || !idCodeCache.equals(idCode)){
                log.error("验证码不正确"+changePwdDTO.toString());
                return ResultFactory.buildFailResult(ResultCode.IDCODE_INCORRECT);
            }

        }else if(repairIndex == 1){
            String oldPassword = changePwdDTO.getOldPassword();
            String digestStr = Utils.digestString(oldPassword,null);
            if(oldPassword == null || oldPassword.trim().length() < 6){
                log.error("旧密码不正确"+changePwdDTO.toString());
                return ResultFactory.buildFailResult(ResultCode.OLD_PASSWORD_INCORRECT);
            }else if(!digestStr.equals(user.getPassword())){
                log.error("旧密码不正确"+changePwdDTO.toString());
                return ResultFactory.buildFailResult(ResultCode.OLD_PASSWORD_INCORRECT);
            }
        }else{
            log.error("未选择密码修改方式"+changePwdDTO.toString());
            return ResultFactory.buildFailResult(ResultCode.CHANGE_PWD_TYPE_NOT_CHOSEN);
        }

        user.setPassword(Utils.digestString(newPassword,null));
        userService.updateUserByUniqueKey(user);
        return ResultFactory.buildSuccessResult(null);

    }

}
